Skip to content

Conversation

@elenaf9
Copy link
Contributor

@elenaf9 elenaf9 commented Oct 2, 2025

Contribution description

Extend RPL to allow nodes to switch between DODAGs that belong to the same RPL instance, based on the preference in the objective function.

This is needed, e.g., for joining a new DODAG version of the same DODAG, or to switch to another DODAG that belongs to the same RPL instance but has a different ID (and thus different root) and better properties.

Based on the RFC sections 6550#3.2, 6550#8.2 and 6552#4.2.

cc @benpicco

Testing procedure

Can be tested with a network of min. 4 nodes using the gnrc_networking example:

  • Start 3 nodes N{1-3} and connect them in a line.
  • Init as N1 root for DODAG ID 2001:db8:1::1
    => N2 and N3 will join the DODAG with rank 256 and 512 respectively.
  • Init 4th node N4 also as root for the same RPL instance, but with with a different DODAG ID (e.g., 2001:db8:1::2).
  • Connect N4 to other nodes.
    => N1 and N2 will stay in previous DODAG 2001:db8:1::1, N3 will switch to new DODAG 2001:db8:1::2 because it will result in a better rank (256 instead of 512).

Prior to this PR, N{1-3} would have just blindly rejected the DIOs from N4 instead of comparing its parameters against their current DODAG.

Open Question

Should we remove a public IP address from an interface when we leave the DODAG that we got the prefix from?
So far, we've keep the IP (also when leaving a DODAG because, e.g., the parent timed out). But if we then join another DODAG with different prefix, the default CONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF = 2 doesn't allow us to add another address with the new prefix.

Issues/PRs references

Part of #21574 -> needed for switching between floating and grounded DODAGs.

@github-actions github-actions bot added Area: network Area: Networking Area: sys Area: System labels Oct 2, 2025
/* Not used yet */
gnrc_rpl_dodag_t *which_dodag(gnrc_rpl_dodag_t *d1, gnrc_rpl_dodag_t *d2)
int which_dodag(gnrc_rpl_dodag_t *d1, gnrc_rpl_dio_t *dio)
{
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we wanted to compare two gnrc_rpl_dodag_ts, we'd first need to allocate the whole dodag structure based on the DIO, and even create a new RPL instance too because we only support one DODAG per instance.
I don't think this makes sense, given that in practice we only ever compare the info from DIOs with the current DODAG.

Comment on lines -940 to -953
if (GNRC_RPL_COUNTER_GREATER_THAN(dio->version_number, dodag->version)) {
if (dodag->node_status == GNRC_RPL_ROOT_NODE) {
dodag->version = GNRC_RPL_COUNTER_INCREMENT(dio->version_number);
trickle_reset_timer(&dodag->trickle);
}
else {
dodag->version = dio->version_number;
gnrc_rpl_local_repair(dodag);
}
}
else if (GNRC_RPL_COUNTER_GREATER_THAN(dodag->version, dio->version_number)) {
trickle_reset_timer(&dodag->trickle);
return;
}
Copy link
Contributor Author

@elenaf9 elenaf9 Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, different DODAG versions should be treated as different DODAGs because they affect also our parent set etc. (e.g., per RFC all parents in the parent set must be the same DODAG version). So the old logic of just increasing our version and leaving the rest as it is wasn't really RFC conformant.
Is my understanding correct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version number is incremented when something happens that requires that the DODAG be rebuilt. It's not a different DODAG. One should attach to the highest version number (with lollipop numbering, I think)

Copy link
Contributor Author

@elenaf9 elenaf9 Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version number is incremented when something happens that requires that the DODAG be rebuilt. It's not a different DODAG. One should attach to the highest version number (with lollipop numbering, I think)

Yes, that was also my understanding.
But implementation wise, I was thinking that we could still treat a new DODAG version the same as we treat joining a completely different DODAG: clear the parent set, reset trickle, reset other parameters...
The old implementation effectively also just triggered a local repair (=> implemented in RIOT as poising of all ranks and cleanup of the current dodag).

But thinking about it again now, we probably don't want to reset all parameters, like dtsn or DAO sequence.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: I don't think that increasing a DODAG version as a root is currently even implemented in RIOT.

@crasbe crasbe added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Oct 2, 2025
@riot-ci
Copy link

riot-ci commented Oct 2, 2025

Murdock results

✔️ PASSED

523d70e gnrc/rpl/control_messages: handle DIO of different DODAG

Success Failures Total Runtime
10552 0 10552 08m:36s

Artifacts

@mcr
Copy link
Contributor

mcr commented Oct 2, 2025

Open Question

Should we remove a public IP address from an interface when we leave the DODAG that we got the prefix from? So far, we've keep the IP (also when leaving a DODAG because, e.g., the parent timed out). But if we then join another DODAG with different prefix, the default CONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF = 2 doesn't allow us to add another address with the new prefix.

The DIO has a LifeTime, so only remove it when that expires.
It is acceptable, I think, to send DIOs for all IP addresses.
This low number for CONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF seems wrong to me.

@crasbe
Copy link
Contributor

crasbe commented Oct 21, 2025

You can squash your fixups. As the PR is approved, we can proceed with the merge afterwards :)

@elenaf9 elenaf9 force-pushed the gnrc/rpl/different-dodags branch from 63583f5 to 523d70e Compare October 22, 2025 19:40
@crasbe crasbe added this pull request to the merge queue Oct 22, 2025
Merged via the queue into RIOT-OS:master with commit 08799d9 Oct 22, 2025
25 checks passed
@elenaf9 elenaf9 deleted the gnrc/rpl/different-dodags branch October 23, 2025 05:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: network Area: Networking Area: sys Area: System CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants